package com.ssm.aop;

import com.ssm.util.LogHelper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 性能监控切面
 * 【Spring: AOP应用】使用AOP实现性能监控，监控方法执行时间，记录超过阈值的方法
 * 【Spring: 模块解耦】通过AOP实现业务逻辑和性能监控的解耦
 */
@Aspect
@Component
public class PerformanceAspect {

    /**
     * 【Spring: IOC依赖注入】
     * 使用@Autowired注解注入LogHelper
     */
    @Autowired
    private LogHelper logHelper;

    /**
     * 性能监控阈值，单位毫秒
     */
    private static final long THRESHOLD = 500;

    /**
     * 定义切点，拦截service包下的所有方法
     * 【Spring: AOP切点定义】
     * 使用@Pointcut注解定义切点表达式，拦截服务层的所有方法
     */
    @Pointcut("execution(* com.ssm.service.*.*(..))")
    public void servicePointcut() {}

    /**
     * 定义切点，拦截dao包下的所有方法
     * 【Spring: AOP切点定义】
     * 使用@Pointcut注解定义切点表达式，拦截数据访问层的所有方法
     */
    @Pointcut("execution(* com.ssm.dao.*.*(..))")
    public void daoPointcut() {}

    /**
     * 环绕通知：监控方法执行时间
     * 【Spring: AOP环绕通知】
     * 使用@Around注解实现环绕通知，监控方法执行时间
     * @param proceedingJoinPoint 可执行的连接点
     * @return 方法执行结果
     * @throws Throwable 异常
     */
    @Around("servicePointcut() || daoPointcut()")
    public Object monitorPerformance(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        
        // 如果执行时间超过阈值，记录日志
        if (executionTime > THRESHOLD) {
            String className = proceedingJoinPoint.getTarget().getClass().getName();
            String methodName = proceedingJoinPoint.getSignature().getName();
            logHelper.warn("性能警告: " + className + "." + methodName + " 执行时间: " + executionTime + "ms");
        }
        
        return result;
    }
} 